<template>
  <a class="main" @click="send">
    <slot></slot>
  </a>
</template>

<script lang="ts" setup>
import { nextTick, onMounted, ref, watch } from 'vue';
import axios from 'axios';
import { ElMessage } from 'element-plus';
import config from '../../config';


const props = defineProps({
  url: {
    type: String,
    default: ''
  },
  method: {
    type: String,
    default: 'post'
  },
  params: {
    type: Object,
    default: () => { return {} }
  },
  //是否当参数变化时自动发送请求
  auto: {
    type: Boolean,
    default: false
  },
  //为false时不允许出现并发请求,如果有请求正在进行中，则后续请求不会发送
  concurrent: {
    type: Boolean,
    default: true
  },
  mountSend: {
    type: Boolean,
    default: true
  },
});
const emits = defineEmits(["onResult"]);
const data = defineModel();
const isLoading = defineModel('loading', {
  default: false,
  type: Boolean
});

let lastParams;
function send() {
  if (!props.url) {
    return;
  }
  if (!props.concurrent && isLoading.value) {
    return;
  }
  nextTick(async () => {
    try {
      const params = JSON.parse(JSON.stringify(props.params));
      lastParams = params;
      isLoading.value = true
      const res = await axios({
        method: props.method,
        url: props.url,
        params: params,
        data: params,
        timeout: config.http.timeout
      });
      if (props.concurrent) {
        if (JSON.stringify(params) != JSON.stringify(lastParams)) {
          return;
        } else {
          isLoading.value = false;
        }
      } else {
        isLoading.value = false;
      }
      if (res.data.code === config.http.successCode) {
        data.value = res.data.data
        emits('onResult', data.value);
      } else {
        ElMessage.error('请求失败，请重新尝试！');
      }
    } catch (error) {
      console.error(error);
      isLoading.value = false;
    }
  })
}


if (props.auto) {
  watch([() => props.params], send, { deep: true, immediate: true });
} else {
  onMounted(() => {
    props.mountSend && send();
  })
}
defineExpose({
  send,
})

</script>
<style scoped>
.main {
  display: inline-flex;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
}
</style>